package com.qingyun.form.provider

import com.qingyun.form.entity.FormSelectItem
import kotlin.collections.forEach

abstract class FormDataProvider {
    /** 值为key的数据列表 */
    protected val dataMap: MutableMap<String, FormSelectItem> = mutableMapOf()

    /** 路径分隔符 */
    var pathSeparator: String = "/"

    /** 是否允许选择父节点 */
    var enableCheckParent: Boolean = false

    /** 过滤条件 */
    var filter: String? = null

    open fun addData(items: List<FormSelectItem>) {
        val dataList = mutableListOf<FormSelectItem>()
        items.sort().forEach {
            expandChildItems(dataList, it)
        }
        dataList.forEach { item ->
            dataMap[item.value] = item
        }
    }

    protected open fun expandChildItems(
        items: MutableList<FormSelectItem>,
        item: FormSelectItem,
    ) {
        items.add(item)
        if (item.hasChildren) {
            item.children!!.forEach {
                expandChildItems(items, it)
            }
        }
    }

    protected open fun List<FormSelectItem>.sort(): List<FormSelectItem> {
        return this.sortedWith { a, b ->
            when {
                a.hasChildren -> -1
                b.hasChildren -> 1
                else -> 0
            }
        }
    }

    open fun getItems(selectedItem: FormSelectItem? = null): List<FormSelectItem> {
        selectedItem ?: return getRootItems()
        if (selectedItem.parent == null) {
            return getRootItems()
        }
        val items = findChildren(selectedItem)
        if (items.isEmpty()) {
            return selectedItem.parent!!.children!!
        }
        return items
    }

    protected open fun findChildren(item: FormSelectItem): List<FormSelectItem> {
        return dataMap.values.filter {
            if (filter.isNullOrEmpty()) {
                it.parent == item
            } else {
                it.parent == item && it.value.startsWith(filter!!)
            }
        }
    }

    protected open fun getRootItems(): List<FormSelectItem> {
        return dataMap.values.filter {
            if (filter.isNullOrEmpty()) {
                it.parent == null
            } else {
                it.parent == null && it.value.startsWith(filter!!)
            }
        }
    }

    open fun getNavigationTitle(item: FormSelectItem): String {
        val parentList = mutableListOf<FormSelectItem>()
        findParents(item, parentList)
        parentList.reverse()
        return parentList.joinToString(pathSeparator) { it.label }
    }

    protected open fun findParents(
        item: FormSelectItem,
        items: MutableList<FormSelectItem>,
    ) {
        val parent = item.parent ?: return
        items.add(parent)
        findParents(parent, items)
    }

    open fun getItem(value: String): FormSelectItem? {
        if (filter.isNullOrEmpty()) {
            return dataMap[value]
        }
        return dataMap["$filter.$value"]
    }

    open fun getItemLabel(value: String): String? {
        return getItem(value)?.label
    }

    open fun getFullLabel(item: FormSelectItem): String? {
        val parent = getNavigationTitle(item)
        if (parent.isEmpty()) {
            return item.label
        }
        return "$parent$pathSeparator${item.label}"
    }

    open fun getItemValue(value: String): String? {
        return if (filter.isNullOrEmpty()) {
            value
        } else {
            val replaceText = if (filter!!.endsWith(".")) filter!! else "$filter."
            value.replace(replaceText, "")
        }
    }
}